package command

import (
	"os"
	"encoding/json"
	"path/filepath"

	"db"
	"ovs"
	"utils"
	ipam "ipamdriver"

	log "github.com/sirupsen/logrus"

)

var (
	configPrefix  =    "config"
	poolPrefix    =    "info"
	nicPrefix     =    "config/nic"
)

const (
	FvBridge = "ovs-fv"
)

var (
	ovsClietnt = ovs.New(
		ovs.Sudo(),
	)
)


type HostPort struct {
	Container   string
	Ports       []string
}


type Config struct {
	Debug        bool
	Turnofffv    bool
	Vlanpool     string
	Vxlanpool    string
	Natpool      string
	Nonatpool    string
	Etcd 		 string
	Nic 		 string
	EtcdPre      string
}

// init log level.
func InitializeLog(debug bool) {
	log.SetOutput(os.Stderr)
	if debug {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}
}

// etcd init etcd store db
func InitEtcd(addr, prefix string)  {
	db.SetDBInfo(addr, prefix)
}

// init the fv bond nic 
func InitNic(nic string) error {
	// check ovs bridge fv
	bridges, _ := ovsClietnt.VSwitch.ListBridges()
	// create ovs-fv and add nic to ovs-fv
	if !utils.IsContain(bridges, FvBridge) {
		if err := ovsClietnt.VSwitch.AddBridge(FvBridge); err != nil {
			log.Fatalf("failed to add bridge: %v", err)
			return err
	    }
		if err := ovsClietnt.VSwitch.AddPort(FvBridge, nic); err != nil {
			log.Fatalf("failed to add bridge: %v", err)
			return err
		}
    }else {
		ports, _ := ovsClietnt.VSwitch.ListPorts(FvBridge)
		if !utils.IsContain(ports, nic) {
			if err := ovsClietnt.VSwitch.AddPort(FvBridge, nic); err != nil {
				log.Fatalf("failed to add bridge: %v", err)
				return err
			}
		}
	}
	return nil
}

func InitPool(pool map[string]string) error {
	for key, value := range pool {
		info := ipam.Pool {
			Network: value,
			Current: "0",
			Recovery: ipam.Queue{
				Items: make([]string, 0, 1),
			},
		}
		data, err := json.Marshal(info)
		if err != nil {
			return err
		}
		if err := db.SetKey(filepath.Join(key, poolPrefix), string(data)); err != nil {
			return err
		}
	}
	return nil
}


// turn off flat vlan feature
func InitConfig(debug, turnofffv bool, etcd, nic, nonatpool, natpool, vlanpool, vxlanpool, 
								flatstartip, flatendip, prefix string)  error {
	config := Config {
		Debug:    	 debug,
		Turnofffv:   turnofffv,
		Etcd:		 etcd,
		Nic:		 nic,
		Vxlanpool:   vxlanpool,
		Vlanpool:    vlanpool,
		Natpool:     natpool,
		Nonatpool:   nonatpool,
		EtcdPre: 	 prefix,
	}
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	if err := db.SetKey(configPrefix, string(data)); err != nil {
		return err
	}	
	return nil
}

